#pragma once
#include <bits/stdc++.h>
using namespace std;

template <typename Object>
class Vector
{
public:
    explicit Vector(int initsize = 0) : thesize{ initsize },theCapacity{ intSize +SPARE_CAPACITY }
    {objects = new Object[ theCapacity]; }
Vector( const Vector & rhs):thesize{rhs.thesize},thecapacity{ rhs.thecapacity}, objects{ nullptr}
    {
	objects=new Object[ thecapacity];
	for(int k=0;k<thesize;++k)
	    objects[k]=rhs.objects[k];
    }

    Vector & operator= (const Vector & rhs)
    {
	Vector copy= rhs;
	swap( *this, copy);
	return *this;
    }

    ~Vector()
    {delete []objects;}

Vector( Vector && rhs):theSize{ rhs.theSize },theCapacity{ rhs.theCapacity },objects{ rhs.objects }
    {
	rhs.objects = nullptr;
	rhs.theSize = 0;
	rhs.theCapacity = 0;
    }


    //overload operator
    Vector & operator=(Vector && rhs)
    {
	swap(theSize,rhs.theSize);
	swap(theCapacity,rhs.theCapacity);
	swap(objects,rhs.objects);
	return *this;
    }

    //change the size of class

    void resize (int newsize)
  {
    if( newSize > theCapacity)
      reserve( newSize * 2);
    theSize = newSize;
  }

  void reserve(int newCapacity)
  {
    if(newCapacity < theSize)
      return;
    
    Object *newArray = new Object[newCapacity];
    for(int k=0; k<theSize ;++k)
      newArray[k] = move(objects[k]);

    theCapacity = newCapacity;
    swap(objects,newArray);
    delete [] newArray;
  }

  //overload operator
  Objects & operator[](int index)
    {return objects[index];}
  const Object & operator[](int index) const
  {return objects[index];}

  //check whether it is a zero group
  bool empty() const
  { return size()==0;}
  
  //retrieves elements from a class
  int size() const
  {return theSize;}
  int capacity() const
  {return theCapacity;}

  //add an element
  void push_back(const Objects & x)
  {
    if(theSize == theCapacity)
	reserve(2*theCapacity+1);
    objects[theSize++] = x;
  }

  void push_back(Object && x)
  {
    if(theSize==theCapacity)
      reserve(2*theCapacity+1);
    objects[theSize++]=move(x);
  }

  void pop_back()
  {
    --theSize;
  }

  //find the last element
  const Object & back () const
  {
    return objects[ theSize-1];
  }

  typedef Obeject * iterator;
  typedef const Object * const_iterator;

  iterator begin()
  {return &objects[0];}
  const_iterator begin() const
  {return &objects[0];}
  iterator end()
  {return &objects[ size() ];}
  const_iterator end() const
  {return &objects[ size() ];}

  static const int SPARE_CAPACITY = 16;

 private:
  int theSize;
  int theCapacity;
  Object * objects;
};
	
    
